package com.tangyuan.live.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tangyuan.common.config.RedissonConfig;
import com.tangyuan.common.result.Result;
import com.tangyuan.common.result.ResultCodeEnum;
import com.tangyuan.common.util.CommStatus;
import com.tangyuan.live.entity.enums.LiveManagementTypeEnum;
import com.tangyuan.live.entity.vo.LiveRoomVo;
import com.tangyuan.live.mapper.LiveViewRecordMapper;
import com.tangyuan.live.service.LiveManagementService;
import com.tangyuan.live.service.LiveRoomService;
import com.tangyuan.live.service.LiveViewRecordService;
import com.tangyuan.live.util.IMUtil;
import com.tangyuan.model.User;
import com.tangyuan.model.live.LiveRoom;
import com.tangyuan.model.live.LiveViewRecord;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class LiveViewRecordServiceImpl extends ServiceImpl<LiveViewRecordMapper, LiveViewRecord>
    implements LiveViewRecordService {

    @Autowired
    LiveRoomService liveRoomService;
    @Autowired
    LiveManagementService liveManagementService;
    @Autowired
    IMUtil imUtil;
    private final RedissonClient redissonClient = RedissonConfig.createRedissonClient();
    @Override
    public Long getMaxViewNumber(Long roomId) {
        return baseMapper.getMaxViewNumber(roomId);
    }
    @Override
    public Result<Long> getOnLineNumber(Long roomId){
        Result<LiveRoom> result = liveRoomService.getLiveRoomById(roomId);
        if(!result.isOk()){
            return Result.build(0L,result.getCode(),result.getMessage());
        }
        LiveRoom data = result.getData();
        return Result.ok(imUtil.getOnLineNumber(data.getGroupId()));
    }

    /**
     * 进入或退出直播间
     * @param token 用户鉴权
     * @param roomId 房间ID
     * @return 直播信息
     */
    @Override
    public Result<LiveRoomVo> inOrOutLive(String token, Long roomId) {
        User user = CommStatus.getUser(token);
        if(user == null){
            return Result.build(null,ResultCodeEnum.LOGIN_AUTH);
        }
        if(user.getIsCreateIm() == null || user.getIsCreateIm() != 0){
            return Result.build(null, ResultCodeEnum.NO_LIVE_VIEW_PERMISSIONS);
        }
        Long userId = user.getId();
        Result<LiveRoom> result = liveRoomService.getLiveRoomById(roomId);
        if(!result.isOk()){
            log.error("用户进入直播失败,直播间Id参数异常.直播间Id:{},校验结果:{}",roomId,result.getMessage());
            return Result.build(null,result.getCode(),result.getMessage());
        }
        LiveRoom liveRoom = result.getData();
        boolean shutUp = liveManagementService.isShiftOutOrShutUp(userId, liveRoom.getId(), LiveManagementTypeEnum.SHIFT_OUT.type);
        if(shutUp){
            return Result.build(null, ResultCodeEnum.BY_SHIFT_OUT);
        }
        if(userId.equals(liveRoom.getUserId())){
            return Result.ok(liveRoomService.getLiveRoomVo(liveRoom,false));
        }
        RLock lock = redissonClient.getLock("liveView:" + roomId);
        lock.lock(10, TimeUnit.SECONDS);
        try {
            LiveViewRecord viewRecord = getLiveViewRecord(userId, roomId);
            if(viewRecord == null){
                viewRecord = new LiveViewRecord();
                viewRecord.setUserId(userId);
                viewRecord.setRoomId(roomId);
                viewRecord.setViewTime(new Date());
                baseMapper.insert(viewRecord);
            }else {
                if(viewRecord.getInOrOut() == 0){
                    viewRecord.setInOrOut(1);
                    baseMapper.updateById(viewRecord);
                    return Result.ok();
                }else {
                    viewRecord.setInOrOut(0);
                    viewRecord.setViewTime(new Date());
                    baseMapper.updateById(viewRecord);
                }
            }
        }catch (Exception e){
            lock.unlock();
            log.error("用户进入直播间保存数据失败,userId:{},roomId:{},异常:{}",userId,roomId,e.toString());
        }
        return Result.ok(liveRoomService.getLiveRoomVo(liveRoom,false));
    }

    @Override
    public List<LiveViewRecord> getViewRecordByRoomId(Long roomId, List<Long> userIds) {
        return baseMapper.selectList(new LambdaQueryWrapper<LiveViewRecord>()
                .in(LiveViewRecord::getUserId, userIds)
                .eq(LiveViewRecord::getRoomId, roomId));
    }

    public LiveViewRecord getLiveViewRecord(Long userId, Long roomId) {
        List<LiveViewRecord> byGroupId = getViewRecordByRoomId(roomId, Collections.singletonList(userId));
        if(CollectionUtils.isEmpty(byGroupId)){
            return null;
        }
        return byGroupId.get(0);
    }
}




